
#include "RobboLito.h"
#include "RobboTotalBase.h"
#include "RobboTripleBase.h"

#define VERBOSO FALSE

uint64 bytesTRIPLE = 0, indTRIPLE = 0, indTRIPLEx = 0;
void load_triple (char *fnin, char *DIR)
{
  int u, i, by, n, j, PR, ni, s;
  char FN[1024], NOME[1024];
  RobboTripleBase *triple;
  FILE *file;
  char TEMP[1024];
  strcpy (NOME, fnin);
  strcpy (TEMP, fnin);
  if (TEMP[0] == 'K' || TEMP[0] == 'k')
    un_windows_triple (TEMP);
  s = strlen (TEMP);
  triple = TABLE_TRIPLE_BASES + NUM_TRIPLE_BASES;
  sprintf (FN, "%s/%s%s", DIR, TRIPLE_PREFISSO, NOME);
  file = fopen (FN, "rb");
  if (file == NULL)
    {
      printf ("No file %s\n", FN);
      return;
    }
  if (VERBOSO)
    printf ("RobboTriple %d %s ", NUM_TRIPLE_BASES, FN);
  for (i = 1; i <= 4; i++)
    TEMP[s + i] = 0;
  robbo_triple_utilita (triple, TEMP);
  triple->data = triple->ind = NULL;
  for (i = 1; i <= 3; i++)
    {
      u = fgetc (file);
      triple->w[i] = u;
    }
  if (triple->w[2] == 0)
    {
      triple->w[3] = 0;
      fclose (file);
      file = 0;
      NUM_TRIPLE_BASES++;
      if (VERBOSO)
	printf ("una resulta %d\n", triple->w[1]);
      return;
    }
  fgetc (file);
  for (i = 1; i <= 3; i++)
    triple->wi[triple->w[i]] = i;
  if (VERBOSO)
    printf ("w: %d/%d/%d  ", triple->w[1], triple->w[2], triple->w[3]);
  by = 0;
  for (i = 0; i < 4; i++)
    by += (fgetc (file) << (8 * i));
  if (VERBOSO)
    printf ("%d by  ", by);
  n = 0;
  for (i = 0; i < 4; i++)
    n += (fgetc (file) << (8 * i));
  if (VERBOSO)
    printf ("%d arch  ", n);
  PR = 0;
  for (i = 0; i < 2; i++)
    PR += (fgetc (file) << (8 * i));
  if (VERBOSO)
    printf ("PR %d  ", PR);
  for (i = 0; i < 2; i++)
    fgetc (file);
  ni = by / PR;
  triple->prop_ind = PR;
  NUM_TRIPLE_BASES++;
  u = ni;
  i = 0;
  while (u >>= 1)
    i++;
  triple->bs = i - 1;
  triple->index = (2 << i) - 1;
  triple->ind = malloc ((triple->index + 1) * sizeof (int));
  for (i = 0; i < ni; i++)
    {
      u = 0;
      for (j = 0; j < 4; j++)
	{
	  u += (fgetc (file) << (8 * j));
	}
      triple->ind[i] = u;
    }
  for (i = ni; i < triple->index + 1; i++)
    triple->ind[i] = (n * 4);
  triple->by = by;
  bytesTRIPLE += by;
  indTRIPLE += triple->index + 1;
  indTRIPLEx += ni;
  triple->data = malloc (PR * ni);
  triple->cnt = n;
  fread (triple->data, 1, PR * ni, file);
  if (VERBOSO)
    {
      printf ("data: ");
      for (i = 0; i < 10; i++)
	printf ("%x ", triple->data[i]);
    }
  if (VERBOSO)
    printf ("\n");
  fclose (file);
  file = 0;
}

void triple_statistica ()
{
  SEND ("info string %d RobboTripleBases (%dmb): " TYPE_64_BIT " data "
	TYPE_64_BIT "+" TYPE_64_BIT " indici\n",
	NUM_TRIPLE_BASES, 1 + (NUM_TRIPLE_BASES / 256) +
	(int) ((bytesTRIPLE + (indTRIPLE * 4)) >> 20),
	bytesTRIPLE, indTRIPLE, indTRIPLEx);
}

#define WINDOWS_TRIPLE_PREFISSO "triple."
static void add_nome_triple (char* NOME, char *DIR)
{
  int n = strlen (TRIPLE_PREFISSO);
  if (memcmp (NOME, TRIPLE_PREFISSO, n) && memcmp (NOME, WINDOWS_TRIPLE_PREFISSO,n))
    return;
  load_triple (NOME + n, DIR);
}

/********/ /********/ /********/ /********/ /********/ /********/ /********/

#ifdef WINDOWS
void GetTripleBase (char* A)
{
  char B[1024];
  WIN32_FIND_DATA ffd;
  HANDLE hFind = INVALID_HANDLE_VALUE;

  SEND ("info string Reading directory %s\n", A);
  strcpy (B, A);
  strcat (B, "\\*");
  hFind = FindFirstFile (B, &ffd);
  if (hFind == INVALID_HANDLE_VALUE)
    {
      SEND ("info string Directory %s not found\n", A);
      return;
    }
  do
    {
      if (!(ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
        add_nome_triple (ffd.cFileName, A);
    }
  while (FindNextFile (hFind, &ffd));
  FindClose (hFind);
}
#else
#include <fcntl.h>
#include <dirent.h>
#include <string.h>
#include <sys/types.h>

void GetTripleBase (char* A)
{
  DIR* DIR;
  struct dirent DE[1], *ptr;
  SEND ("info string Reading directory %s\n", A);
  DIR = opendir (A);
  if (!DIR)
    {
      SEND ("info string Directory %s not found\n", A);
      return;
    }
  while (1)
    {
      readdir_r (DIR, DE, &ptr);
      if (!ptr) break;
      add_nome_triple (DE->d_name, A);
    }
  closedir (DIR);
}
#endif
